# ifndef NEWTONSOLVER_H
# define NEWTONSOLVER_H

# define _USE_MATH_DEFINES
# include<cmath>
# include"Function.h"

/**
* @brief 定义一个抽象类规范求解器的求解函数接口
*
*/
class EquationSolver
{
public:
    virtual double solve() const = 0;  // 虚类，不得实体化
};

/**
* @brief 实现牛顿迭代法(Newton's method)求零点的求解器
*
*/
class NewtonSolver : public EquationSolver
{
private:
    double x0, eps;
    int M;
    Function & func;

public:
    NewtonSolver(double _x0, double _eps, int _M, Function & _f);
    ~NewtonSolver(){};

    // 求解函数
    double solve() const;
};

/**
* @brief 赋值构造
* 
*/
NewtonSolver::NewtonSolver(double _x0, double _eps, int _M, Function & _f): func(_f)
{
    x0 = _x0; eps = _eps; M = _M;
}

/**
* @brief 求解函数
*/
double NewtonSolver::solve() const
{
    double x = x0, u;
    for (int k = 0; k < M; k++)
    {
        u = func(x);
        if (fabs(u) < eps) break;
        x = x - u / func.diff(x);
    }
    return x;
}

# else
// Do nothing.
# endif